{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "import pandas as pd\n",
    "sns.set(font_scale=1.5)\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from sklearn import linear_model\n",
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.preprocessing import PolynomialFeatures"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part 1: Sin waves\n",
    "In this exercise, you'll use Linear Regression to model a non-linear looking dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "file = r'D:\\Programing\\python_projects\\machine_learning_algorithm\\data_set\\p1.csv'\n",
    "df = pd.read_csv(file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Unnamed: 0</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>-10.104576</td>\n",
       "      <td>-18.450527</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>-10.117579</td>\n",
       "      <td>-18.477500</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>-9.893642</td>\n",
       "      <td>-18.073938</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>-9.754603</td>\n",
       "      <td>-18.039106</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>-9.834811</td>\n",
       "      <td>-18.030060</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Unnamed: 0          x          y\n",
       "0           0 -10.104576 -18.450527\n",
       "1           1 -10.117579 -18.477500\n",
       "2           2  -9.893642 -18.073938\n",
       "3           3  -9.754603 -18.039106\n",
       "4           4  -9.834811 -18.030060"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1ca8e8ee508>]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(df['x'], df['y'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a dataframe called `featurized_p1_data` that has 3 columns:\n",
    "\n",
    "1. `phi1` which just be the same thing as x\n",
    "2. `phi2` which should be sin(x)\n",
    "3. `phi3` which shoudl be sin(5*x)\n",
    "\n",
    "You might find `np.sin` useful."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "dfp1 = pd.DataFrame({\n",
    "    'phi1': df['x'],\n",
    "    'phi2': np.sin(df['x']),\n",
    "    'phi3': np.sin(df['x'] * 5)\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>phi1</th>\n",
       "      <th>phi2</th>\n",
       "      <th>phi3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-10.104576</td>\n",
       "      <td>0.628636</td>\n",
       "      <td>-0.254565</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-10.117579</td>\n",
       "      <td>0.638695</td>\n",
       "      <td>-0.316854</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-9.893642</td>\n",
       "      <td>0.451873</td>\n",
       "      <td>0.715452</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-9.754603</td>\n",
       "      <td>0.323878</td>\n",
       "      <td>0.996934</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-9.834811</td>\n",
       "      <td>0.398640</td>\n",
       "      <td>0.887286</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        phi1      phi2      phi3\n",
       "0 -10.104576  0.628636 -0.254565\n",
       "1 -10.117579  0.638695 -0.316854\n",
       "2  -9.893642  0.451873  0.715452\n",
       "3  -9.754603  0.323878  0.996934\n",
       "4  -9.834811  0.398640  0.887286"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dfp1.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now create a linear regression model called `p1_model` that uses your 3 features to predict `y`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=False, n_jobs=1, normalize=False)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model = linear_model.LinearRegression(fit_intercept=False)\n",
    "p1_model.fit(dfp1, df['y'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The line of code below lets you see the coefficients produced by your model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2. , 3. , 0.5])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model.coef_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And the code below will compute the mean squared error. You/ll see it is very low (almost zero). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.9209584495415156e-28"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_squared_error(p1_model.predict(dfp1), df['y'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code below plots the output of your model, observe that it looks exactly the same as the original data. Our model is perfectly predicting the output.\n",
    "\n",
    "This won't be possible with real data, of course. We were only able to get such good accuracy because the dataset was artificial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1ca8f05c4c8>]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEACAYAAAC+gnFaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3dd1xUZ74G8GdmqDKINBvIKGIsGLEgBrFgWRE12Rg3lhgTFYwaUzTWuEl2k9W9EQuKceO6Cu4mceW6iXpjCcaYWKLGFewgFhCwI0qvw5z7B2HCSJuBmTlTnu/nk8+e856ZOT/ePc4zp74SQRAEEBGR1ZKKXQAREYmLQUBEZOUYBEREVo5BQERk5RgERERWjkFARGTlGARERFbORuwCmurJkyKoVE2/BcLdXY6cnEI9VmS52Fe6YX9pj32lm6b2l1QqgaurU73L9RYEKpUK8fHx2LFjB27fvg13d3eMGDECb7/9NuRyOQDgxIkTiI6Oxo0bN+Du7o5XX30VM2fObOL6hGYFQfVnkHbYV7phf2mPfaUbQ/SX3oJg69atWL9+PSIiIhAcHIz09HTExMTgxo0b2LZtG5KSkjBnzhyEh4fj3XffRWJiIqKioiAIAiIiIvRVBhER6UgvQSAIArZu3YpJkyZh4cKFAICBAwfC1dUVCxYsQEpKCmJiYtCjRw+sXr0aADBkyBAolUps3rwZ06ZNg52dnT5KISIiHenlZHFRURFeeOEFjBs3TqPd19cXAHD9+nWcPXsWo0aN0lgeFhaG/Px8JCUl6aMMIiJqAr0EgVwuxwcffIB+/fpptB8+fBgA0KNHD1RUVKBTp04ayxUKBQAgPT1dH2UQEVETGOzy0QsXLmDLli0YOXIkCgoKAEB90riak1PVWezCQl41QEQkFoNcPpqYmIg5c+bA29sbK1asUP/il0gkdb5eKtU9j9zd5Y2/qBGens7N/gxrwb7SDftLe+wr3Riiv/QeBAcOHMCyZcvQsWNHbN26Fa6urnj06BGA2r/8q+ednXX/w3JyCpt1GZWnpzOyswua/H5rwr7SDftLe9bSV2+s/gnKSpVG26Be7TAjvFu9P5Dr0tT+kkolDf541uuhobi4OLz33nvo3bs3vvrqK7Ru3RoA4OPjA5lMhszMTI3XV88/fe6AiMjUqFQCLt7MwdmrD3EtKxfajOl1804eZn56pFYIAMCJi/fw4bYzUJnA2GB62yPYtWsXPv30U4wZMwarVq3SuBzU3t4egYGBOHToEF5//XV1AiYkJMDZ2Rk9e/bUVxlERHr3zbGb2Hcyo85lf33jObR1a6HRVlquxJvrjmm0/fG1fujc3gUAcPNuHv76RSLuPirCju+vYervntFpz0DfJPoYqjInJwcjRoyAm5sboqKiYGOjmS8+Pj5ITU3FjBkzMHr0aIwfPx7nzp3D5s2bsXDhQsyaNasJ6+ShIWNhX+mG/aU9c+irhkKgps5eLRE+QIHPvrmk0R7ybFtEjO1R6/WCIGDXjzfx3ZlMjBvYES8N8W10HYY6NKSXPYLjx4+jpKQEd+7cwdSpU2stj4qKwu9//3ts3LgRMTExmDdvHtq0aYMlS5Y0+RETRESG9o9vk3Hqyn0AwJzf+6N/t9aQSCRQVqpwLSsXa3aeV7/25p38WiGwZXEobGR1H4GXSCR4eVhnFJdVYN/JW2hhb4PRA3wM98c0QC97BGLgHoHxsK90w/7Snin3VX5ROeZvPAEAiJoTDI9WjvW+9sbtPHz1/TU8598G5UoVwgf41BsAT1OpBGz+vys4e/UhXg7tjNEDfOo9TGTSewRERJZEEARsP3gVNjIpPpoe2GAIAICftwv+NKN/k9YllUrwxvM9IJUAu366icf5ZZgysgukUs0wKClTorCkoknraAyDgIjoKb8kP8D5G48weUQXeHs2/56lxtjIpHjjBX+4OTvguzOZeFxQioixPeBgL8Oe42nqcxQ+bZ3x5+lNC5wG16/3TyQiMmM5eaXY8m0yZFIJRgZ6G229UokEE4f7wbWlPXYevo631h+r9Zq3J/Y2yLoZBERENSz+/CQAYHBAe0hFuKTzd4Ed4NuuJVZ+kahue29iAHr6uhvsnAqDgIjoV5fTctTTr4V1Fa2Ozl4uiF023Gjr45jFRES/Wve/FwAAr4zsInIlxsUgICICkHG/6pBLyLNtMTKwg8jVGBeDgIisniAIiD9yHXJHW0wZYV17AwCDgIgIp5Mf4GpmLl4c3AktHGzFLsfoGAREZNWeFJThq0PX4OftgtDeXmKXIwoGARFZLZVKQOyBFChVKkSM7V7rbl5rwSAgIqskCAJ2HL6GK+mPMXlEF7RxbdH4mywU7yMgIqujEgT858ebOJJ0B6ODfKz2kFA1BgERWZXcwjK899nPAIBhfbzwh2GdRa5IfAwCIrIKgiDg5OX7+Pfh6wCAwK6eeHWUuCODmQoGARFZvOJSpfohbl28XTBzTHe0cbPecwJPYxAQkUXLKyrHgl8HmGnZwhZLp/YV5WFypoxBQEQWq7hUqQ4BAIh+exAPBdWBl48SkcWq+Uz/tfNCGAL1YBAQkUX6x7fJ6unIcd3h6mwvYjWmjUFARBanrKISp67cBwD4d3RFsH9bkSsybQwCIrI4W/f9tjcQMa4HDwk1gkFARBalQqlCYmo2AOC10V3RSs5DQo1hEBCRRVm46Wf19NCA9iJWYj4YBERkMfKLy1FYUgEAWDlrAA8JaYlBQEQWY37Mb/cMtHN3ErES88IgICKLs+bNgWKXYFYYBERkEb49eUs97dbSQbxCzBCDgIgswu5jaQCAxZN7i1yJ+WEQEJHZe5Rbop7u3tFNxErME4OAiMze6eQHAIDp4d1ErsQ8MQiIyKypVAKOXbiLZzq0whDeN9AkDAIiMmuX0nLwKK8Uw/ta97jDzcEgICKzdiTpDlzkduj7jKfYpZgtBgERma2HT4pxOS0HQwPaw0bGr7OmYs8Rkdn68dwdSKUSDO3Nw0LNwSAgIrNUVlGJExfvoc8znhx0ppkYBERklg6ezkBRqRK/C/QWuxSzZ7AgSElJgb+/P+7fv6/RfuLECUyYMAEBAQEYPnw4YmNjDVUCEVmoB0+KceB0JoK6t0YX71Zil2P2DBIEaWlpmD17NpRKpUZ7UlIS5syZA19fX2zcuBHPP/88oqKisG3bNkOUQUQWSBAEbNufAplMgknDu4hdjkWw0eeHKZVKxMfHY+3atbC1ta21PCYmBj169MDq1asBAEOGDIFSqcTmzZsxbdo02NnZ6bMcIrJAiz8/icf5ZQDAcwN6otc9gsTERKxZswYzZ87EokWLNJaVlZXh7NmzGDVqlEZ7WFgY8vPzkZSUpM9SiMgC3X5YqA6BySO4N6Aveg2Czp074/Dhw3jrrbcgk8k0lmVlZaGiogKdOnXSaFcoFACA9PR0fZZCRBamUqXCR7Fn1POj+ncQsRrLotdDQx4eHvUuKygoAADI5XKNdienqlGECgsLdVqXu7u88Rc1wtPTudmfYS3YV7phf2lPm76qVAnYsvuiev7btb83ZEkmzRDbll6DoCGCIABAvWOISqW67Zzk5BRCpRKaXI+npzOyswua/H5rwr7SDftLe9r01aO8Emzbl4LUrFwM7d0er4/uZrX929RtSyqVNPjj2WhB4OxclWJP//Kvnq9eTkRU7eTle/jq+2tQCcCMMd0w6Nl2YpdkkYwWBD4+PpDJZMjMzNRor55/+twBEVmvvMIyLPjsZwCAn7cLZo3rAc9WjiJXZbmMdmexvb09AgMDcejQIfVhIgBISEiAs7MzevbsaaxSiMiEJd96rA4BAFj6Sh+GgIEZ9RETc+fORVJSEhYsWICjR49i/fr12LZtG2bPng1HR/4fTWTtcvJKsWbnefX81qXDINPx/CHpzqg9HBwcjI0bN+LmzZuYN28evv32WyxZsgSzZs0yZhlEZIIEQcDiz0+q57csDoW0notLSL8kQs3jNGaEVw0ZD/tKN+wv7dXsq5mfHlG3r50XwruG62Coq4a4z0VEortxO089HTG2O0PAyBgERCS6v36ZCACwt5MhhJeIGh2DgIhEtfOH6+rpvy0YImIl1otBQESiUakE/JB4GwAQNSe43icPkGExCIhINMfO30GlSsDMMd3hwXsFRMMgICJRlFdU4p/7k+HTRo6Bz7YVuxyrZrRHTBCRuFIzn2DVjnMabbPG9UBwT3G+hA/9NwuPckuwZEof3i8gMgYBkZnJKypHYUkFWrdyhK1N4zv1giAgYtWPdS77x77kqv+WhBr1Dt7L6Tn45lga+nZtjW4KV6Otl+rGICAyE7EHUnDi4r1a7VNGdMHIQO86T7Q+zC3B9gMp6vnwAT54cbAvyioqceBUBr47U/XQx41fX8LbE541ShgIgoB18RcAANPGdDf4+qhxDAIiM/DgSXGdIQAA//7hOv796yWYDnYyvDTEF3lF5dh/KkP9mtdHd8WQgPbqsLC1kWLicD9MHO6HQ//Nws4fruOf36ViRng3g1+5U3PvxM+7Fe/CNgEMAiITV/PYvoeLA6LmDlQvU1aqcPT8XXz1/TUAQGl5JXYcvq7x/k/nBKN1A1fkjOrfAYUlFdh38hZc5fYYP8RX69qu3HqMm3fyYGsjhZeHExztbeDn5VJnmKgEAacu31fPf75wqNbrIcNiEBCZMGWlSuMEb80QAAAbmRQj+nljWB8vnE19iPPXH+F08gMAwPyXe6FX5/qHj61p/OBOyC0sw7cnb8HV2R6hfbwafP2ZlAfYvPdKvctnjeuBwG6tYWsjRaVKhTMpD7H3eDoe5pYAAKaM7AJ7W1m97yfj4kPnqFHsK93os79qPojN0Cd0lZUqfPbNJVxKy0HE2O4Y2LP2ox4e55di0d9OarTNCO+GPs94IuthIVb/+xxsbaSoUKrQ0skO+UXlGq91dbZH1Nxg9d/BbUs3Zj9UJRHppvqOWwD4S+QAg5/ItZFJMff3PbHs76ewdV8Ktu5Lwdp5IXBxskNBcbnGYDEA4O0pxycRQer57gpXxC4bDpUgIDn9MRLOZOLKU0GweEofji9gghgERCaq+rj/Mx1awcvDySjrtLeT4X9mP4c31x0DACzc9HOdr/ts/hC0cKj760MqkaCnrzt6+rrjcX4pLqXloENrZ/i2b2mwuql5GAREJujKrcfq6WVT+xp13Q52NohdNhx//78r+OXX8w3V3pnQC727aHfeAQDcWjpgaO+GzzeQ+BgERCZGpRIQ/8N1eLZywIrI50SrY/YL/pj9gr9o6yfj4cE6IhPzbsxx3M4uwh9C/bS6c5ioubiVEZmQ9Hv5KCpVAgACu3qKXA1ZCwYBkYlQCQL+8s+zAIBhfb34bH4yGgYBkYlYXePGsWmjuopYCVkbBgGRCbiXU4TUrFwAVfcMEBkTg4BIZMpKFf74j18AAD6t5Ua7Z4CoGoOASEQVShXeWP2Tev7PM4PqfzGRgfA+AiKRFJdW4K31x9XzWxaHilcMWTUGAZEIsnNLsHTzKfX8p3OCYSPjDjqJg0FAZGR7T6Rj74l09Xz0WyFwkduLWBFZOwYBkZEIgoDjF++pQ8C9pQOi5gbzfgESHYOAyAgqlCrMXvOTen7xlD7ozkHbyUQwCIiMoGYIbF44FHYcnYtMCIOAyMAu3Hiknt62dBgPBZHJYRAQGdDt7EJs+M9F+LSW44+v9WMIkEni9WpEBvTRtjMAgDkv9oStDQ8HkWliEBAZyI07eQCAoO6t0dathcjVENWPQUBkIN8cvYmWLWwxPbyb2KUQNYhBQGQAybce42pmLsYO7AgHO56KI9PGICAygO/OZMJFbodQDtxOZkCUINi3bx/Gjh2LXr16ITw8HHv27BGjDCKDuPeoCJfTHiO0txfHHCazYPSt9ODBg1i0aBFCQkKwadMmBAUFYenSpfjuu++MXQqRQRw8dQtSiQRDAtqLXQqRVox+8HLdunUIDw/H8uXLAQCDBw9GXl4eNmzYgNGjRxu7HCK9yisqx+6fbqCnrxtcnfkgOTIPRt0jyMrKQmZmJkaNGqXRHhYWhrS0NGRlZRmzHCK9W7DxBADwOUJkVowaBGlpaQCATp06abQrFAoAQHp6eq33EJkLlUpQT48O8hGxEiLdGDUICgoKAAByuVyj3cmpaozWwsJCY5ZDpFdr48+rp/koCTInRj1HIAhVv5ie/kdS3S6Vap9L7u7yxl/UCE9P52Z/hrVgXzUuJeMJACD2g1HwdHUUuRrzwW1LN4boL6MGgbNz1R/w9C//oqIijeXayMkp1NgV15WnpzOyswua/H5rwr5q3Llr2eppT1dH9peWuG3ppqn9JZVKGvzxbNRDQ9XnBjIzMzXaMzIyNJYTmZuN31wCAEwZ0UXkSoh0Z9QgUCgU8Pb2rnXPwKFDh9CxY0e0b8/rrsn8FJVWqKd/17+DiJUQNY3R7yOYN28e3n//fbi4uCA0NBRHjhzBwYMHER0dbexSiPRi0aaTVf87ubfIlRA1jdGD4KWXXkJ5eTliY2Oxa9cudOjQAatWrcKYMWOMXQpRs6lUAsoqKgEAfl4uIldD1DSiPBZx8uTJmDx5shirJtKryKgf1dMch5jMFZ+IRdRE1Zc9A8D/zH5OxEqImodBQNRECz77WT3dxpUjkJH5YhAQNcGjvBLkF5UDAD6bP1jkaoiah0FA1ARLPj8FAOjm0wotHGxFroaoeRgERDqau/aoenrJK31FrIRIPziYKpGWBEHAlm+T1ZeLRs0NFrkiIv1gEBBpobRciTfXHVPP/31RKIehJIvBICBqRGJqNjbtvqSeX/PmQIYAWRQGAVEDFv/tZ+Tkl6nnty0dxrEGyOIwCIjqoBIERK767a7hicP8MHoARx0jy8QgIKpDzRBY//YgtHSyE7EaIsNiEBA9ZeanR9TTscuGi1gJkXHwjBdRDf9KSFVP/+29ISJWQmQ8DAKiX6kEAT+duwMACB/gAwc77jCTdWAQEP2q5nmBl4f5iVgJkXExCIgAXErLUU+veXOgiJUQGR+DgAhA9P9eUE+7tXQQsRIi42MQkNWreYJ429JhIlZCJA4GAVm1mieIZ4zpxruGySrxsggyKkEQ8NcvEnHzbr66LWpOMDxaOYpSz57j6erpwb3ai1IDkdi4R0BNphIEjXF7G/PTuTuIWPWjRggAwJLNp3Am5YFOn6UPJWVK7Dt5C0DV00SJrBX3CEhnTz+NEwBkUgk+XzgUNrLavy3yi8oxf+MJjTa5oy1WRA5AQXE5Yg+kYPPeKzh3/REixnav8zMMYV501WOlZ4R349NEyaoxCEhrGfcLsOJfZ1Gpqv3LvVIl4I3VPwEA5r7YEwGd3SFAczQvAJgw1BejB/hAJq364m3pZIfl0/rhwKkM7D6eDqlEgohx3SE18LH6qB1J6ulBvdoZdF1Epo5BQFopLlXi4+3/Vc+PeU6B5wd2hL2dDEnXsvHZN7/tIXy+53Kt97dzb4FPIoLUAVCTTCrF8yGdAIkEu4+lwcnRBlNGdNH6xK1KJSDm64u4eScPg3u1x5hgBeSOdY8jrKxUIeFMJq5m5gIAXgjpyBPEZPUkgrEPzOpJTk4hVHX8MtWWp6czsrML9FiR5fL0dMbzC/eq5/8SOQBeHk61XqesVOHLQ9dw7MJdjfZNC4bA0b7x3xyCIGDnDzfw/dksuLW0x5o3Qxp8fXlFJeY8tccBALY2Ugzo3gYj+nlD0dZZXdupy/fx7clbeJRXqn6tIR4qx21Le+wr3TS1v6RSCdzd5fUuZxBQo1Lv5mPVv84CMPzALE+PA1DfF/UXh1LxY9IdjTY/LxcM7d0eN+/m4+TleyivUNV6X2tXRzx8UoJnOrTCsqmGGXie25b22Fe6YRA8hUFgHIUlFXhnw3EAVY9eMMZdtzXXCQBr54XA1dkeAJCdW4Klm09pvD7m3cG1DgUVl1bgP0fT1PcIVBsbrMCEoZ0NVHkVblvaY1/phkHwFAaBcVQ/m1/uaIuYdwcbbb0PnhTj/b+fbvA1y6f1g5+XS6OfdfHmI6TdzYdbSwcM7NnW4FclcdvSHvtKN4YKAp4spnqdv/5IPb3+nUFGXXcb1xbYtnQY/hR7BrezizSWzXq+B4L922r9Wb06e6BXZw99l0hkMRgEVK+Yry8CAOa81Mvgl3PWRSKR4JOIAQCqTiSrBKHOq46IqHn4r4rqtHbnOfX02JBOIlZSRSKRMASIDIT/sqiWkjIlrtx6AoDP5ieyBgwCqqX60Qst7G34bH4iK8AgIA01TxBvnG+8q4SISDwMAlITBEF9gnjiMD8+eoHISjAISC2ixh29owf4iFgJERkTg4AAAImpD9XTK2cNELESIjI2gwTBqlWrMH369FrtSqUS69evx9ChQxEQEIBXXnkFFy9eNEQJpIOUjCfYtLvqiaFjgxVo5177gXJEZLn0HgRffvklYmNj61y2cuVKbN++HbNmzUJ0dDRkMhmmT5+OrKwsfZdBWlry+Ums/nfVPQNr3hxo8OfwEJHp0VsQPHjwAAsXLsTKlSvh7Oxca/nt27cRHx+PpUuX4tVXX8Xw4cOxbds2uLi4YOvWrfoqg7RUUqbEX/55Vv1I5vkv9+KlokRWSm9BEB0djeTkZMTFxaF79+61lp8+fRqVlZUICwtTt9nZ2SE0NBTHjh3TVxmkhZt38/Cn2DNIv1c1dvCaNwfyWTxEVkxvzxqKjIyEr68vpFIpNm3aVGt5WloaXFxc4ObmptGuUChw9+5dlJaWwsGBv0gN7cbtPKyNPw/nFrZYNrUvnunQSuySiEhkjQaBUqnE/v37613u4eGBkJAQ+Pn5Nfg5hYWFkMtrPwbVyanqxGRRURGDwMBu3c9H9K7zaCW3w9KpfdFKbi92SURkAhoNgrKyMixZsqTe5UFBQQgJaXhIQaDqZqWG2nW9eamhZ2try9Oz9rkMS3XrXj6i//cCnJ3s8T9vDoKnq6NO77emvtIH9pf22Fe6MUR/NRoETk5OSE1NbfaK5HI5ioqKarVXt9W1t9AQDkyjPWWlCp9u/y+kUgnemxgAKJU6/e3W1Ff6wP7SHvtKN4YamMZoN5T5+voiNzcXeXl5Gu0ZGRnw9vaGnZ2dsUqxOkeS7uDOoyK8NqorWrfSbU+AiCyf0YJg4MCqxxknJCSo28rLy3H06FH1MtK/vMIy7D2Rhp6+bujdhVcGEVFtRhuhzMvLC+PHj8eKFStQXFwMhUKBuLg45OXlITIy0lhlWJ39pzJQXqHCKyOf4UPkiKhORh2q8pNPPkHLli2xZcsWFBcXw9/fH3FxcVAoFMYsw2oUl1bg+MV7COreBm3dWohdDhGZKIlQ3+U8Jo4nixv36ZeJuHY7D3+a3h+Ktk2/0sAa+kqf2F/aY1/pxuxPFpNx5ReV49rtqhPzzQkBIrJ8DAILNX/jCQAMASJqHIPAAtU82vfha4EiVkJE5oBBYIFi96eop6VSXilERA1jEFigq5lPAAB/feM5kSshInPAILAwRaUVKCiuwNDe7XnJKBFphUFgYX6+dB/lShWG9fESuxQiMhMMAguiEgT8mHQbfl4u8GnDq4WISDsMAguSkvEED56UcG+AiHTCILAgPyXdgdzRFoHdPMUuhYjMCIPAQjzKLcG5648wuFc72NrIxC6HiMwIg8BCJJzJgkQCjOjnLXYpRGRmGAQW4ElBGX5Iuo1g/7Zwa8lxn4lINwwCC7Bw088AgGF9eZKYiHTHIDBztx8Wqqc7tWspYiVEZK4YBGZMJQj4KPYMACDm3cEiV0NE5opBYMYiV/2onpY72opYCRGZMwaBmbqXU6Se3rRgiIiVEJG5YxCYoYe5JYj5z0UAwJsv9oSjvVGHniYiC8NvEDOTmvkEm3ZfhiAIWDa1L57p0ErskojIzDEIzERBcTn+ffg6fkl5gLZuLfDOH3qhjSsfM01EzccgMAN/23MZZ68+BAAM7tUOk4Z3QQsH/l9HRPrBbxMTd+rKfXUIdG7fEjPGdBe5IiKyNAwCE/bHf5zGvZxiAMDyaf3g5+UickVEZIkYBCZq97E0dQh8PDMIHVrLRa6IiCwVLx81QcpKFb49eQtA1eWhDAEiMiQGgQnafSwNADBlZBcEdmstcjVEZOkYBCbm+u1cfPdLJoYEtMfvAjuIXQ4RWQEGgQlRCQJ2fH8drZztMXmEn9jlEJGVYBCYkJOX7iPjQQH+ENoZDnY8j09ExsEgMBGl5Up8fewmOrVriQE92ohdDhFZEQaBiTh4OhN5heWYMqILpBKJ2OUQkRWx2uMPOXkl2PTNJSReywYAfPh6oGgjfD3OL0XCmUwEdW8NP2/eNEZExmV1QaCsVCHhTCb2ncpAWXmluv0v/zwLBzsZ/vbeUKPX9J+jNyEA+ENoZ6Ovm4jIqoLg8Nks7Dh8HQAQ/Gw7hAd1gIOdDEs+PwUAKC2vxMxPj2DL4lDYyIxz1Ozm3TycvvIAY4MV8HBxNMo6iYhqsqpzBPFHbgAAFkwMwPLpQfD2lMPDxRGxy4ZrjPL1971XIAiCwespr6hE3IGraCW3w5jnFAZfHxFRXaxqjyDm3cGwtZHW+Wvf0d4G25YOw84fbuD7s1nYd/IWng/ppNPnP84vxb2cYrjI7dDG1RG2NrJ6X/sor0S9J/LexACOMkZEotHbt092djY2bNiAn3/+Gbm5uejUqRNmzZqF8PBw9WuUSiU+++wz7N69G7m5ufD398eyZcvQq1cvfZXRoMa+bCUSCSaN8ENhSQV2H0+H3NEWw/p6N/q5Xx+9if2nMupc9ucZ/eHTxlk9/yivBAdOZeD4xXvqtp6+7lr+BURE+qeXICgvL0dkZCQKCgrwzjvvoHXr1khISMD8+fNRWVmJcePGAQBWrlyJ3bt3Y9GiRWjfvj3i4uIwffp07N27Fx06mMbjFKQSCWaM6Yai0gp8cegaSsorET7AB5I6LumsUFZi/a6LSMl4AgCwt5PhuR5tIAgCjl2o+qL/c9x/0bGtM9p7OOHk5fsa7180uTe6K1wN/0cRETVAIujhYPjhw4cxb9487Nq1S+PXfWRkJLKzs7F3717cvn0bo0aNwocffogpU6YAqAqQsLAwDBkyBB9//LFO68zJKYRK1fTSPT2dkZ1dUMc1D9kAAAnKSURBVO/yCqUK2/Yn40xK1aAw08O7waeNHO3cnWBvK8PVjCf4Z0IqHjz+dbyAV/vVuvSzsKQCp67cx7ELd3Enu0hjmZ+3C5ZN7WsW9ww01lekif2lPfaVbpraX1KpBO7u9T/FWC97BE5OTpg0aRKeffZZjXZfX18kJiYCAE6fPo3KykqEhYWpl9vZ2SE0NBQ//fSTPsrQK1sbKd54wV8dBNsPXq31Gg8XByyc1Bv+ndzq/Ay5oy1+F9gBI/t5I/ZACpJvPcHKWQP4+AgiMil6+UYKDg5GcHCwRltFRQWOHj2KLl26AADS0tLg4uICNzfNL02FQoG7d++itLQUDg4O+ihHb6QSCbYuHYbPvr6E8zceaSwL6OyOOS/2hL1t/SeEq0kkEkSM7WGoMomImqXRIFAqldi/f3+9yz08PBASElKrfc2aNbh16xY2bdoEACgsLIRcXnvXxMnJCQBQVFRkckEAVIXBO3/47XDXo9wSuLV0gFRq+od0iIi00WgQlJWVYcmSJfUuDwoK0ggCQRCwevVqbN++HRERERg5cqS6vS7V7XWdjG1IQ8e7tOXp6dz4i/TwHktgrX93U7G/tMe+0o0h+qvRIHByckJqaqpWH1ZeXo5ly5Zh//79iIiI0AgQuVyOoqKiWu+pbqtrb6Ehhj5ZTL9hX+mG/aU99pVuTPpkMVB16Gf27NlISkrC8uXL8frrr2ss9/X1RW5uLvLy8uDi8tvVNRkZGfD29oadnZ2+SiEiIh3o5RETlZWVmDt3Li5cuIB169bVCgEAGDhwIAAgISFB3VZeXo6jR4+qlxERkfHpZY9g586dOHPmDCZNmoR27drh/Pnz6mUSiQQBAQHw8vLC+PHjsWLFChQXF0OhUCAuLg55eXmIjIzURxlERNQEegmC6l/58fHxiI+P11gmk8mQnJwMAPjkk0/QsmVLbNmyBcXFxfD390dcXBwUCj5wjYhILHq5s1gMPFlsPOwr3bC/tMe+0o3Jnyw2Nn1cx897AbTHvtIN+0t77CvdNKW/GnuP2e4REBGRfljVwDRERFQbg4CIyMoxCIiIrByDgIjIyjEIiIisHIOAiMjKMQiIiKwcg4CIyMoxCIiIrJzVBsGqVaswffr0Wu1KpRLr16/H0KFDERAQgFdeeQUXL140foEmaO/evejatWut/z755BOxSzMJ+/btw9ixY9GrVy+Eh4djz549YpdkkpRKJXr16lVrO+rTp4/YpZmUlJQU+Pv74/79+xrtJ06cwIQJExAQEIDhw4cjNja22esy22cNNceXX36J2NhYBAcH11q2cuVK7N69G4sWLUL79u0RFxeH6dOnY+/evejQoYMI1ZqOq1evQqFQICoqSqPdw8NDpIpMx8GDB7Fo0SK89tprGDx4MA4fPoylS5fCwcEBo0ePFrs8k5Keno6ysjKsWrUKHTt2VLdLpVb7u7SWtLQ0zJ49G0qlUqM9KSkJc+bMQXh4ON59910kJiYiKioKgiAgIiKiyeuzqiB48OABoqKicODAATg71x738/bt24iPj8eHH36IKVOmAAAGDRqEsLAwbN26FR9//LGxSzYpqamp8Pf3R+/evcUuxeSsW7cO4eHhWL58OQBg8ODByMvLw4YNGxgET7l69SqkUinCwsLg6OgodjkmRalUIj4+HmvXroWtrW2t5TExMejRowdWr14NABgyZAiUSiU2b96MadOmNXmkR6uK4OjoaCQnJyMuLg7du3evtfz06dOorKxEWFiYus3Ozg6hoaE4duyYMUs1SVevXkXXrl3FLsPkZGVlITMzE6NGjdJoDwsLQ1paGrKyskSqzDSlpKTAx8eHIVCHxMRErFmzBjNnzsSiRYs0lpWVleHs2bN1bmf5+flISkpq8nqtKggiIyOxf/9+PPfcc3UuT0tLg4uLC9zc3DTaFQoF7t69i9LSUmOUaZIePnyInJwcJCcnY/To0fD390dYWBiPg6NquwGATp06abRXD7iUnp5u9JpMWWpqKuzs7BAREYE+ffqgf//++Oijj1BYWCh2aaLr3LkzDh8+jLfeegsymUxjWVZWFioqKgyynVnEoSGlUon9+/fXu9zDwwMhISHw8/Nr8HMKCwshl9cevMHJyQkAUFRUBAcHh+YVa4K06b/KykoAVYfPFi9eDHt7e+zZswdLly5FZWUlJkyYYKxyTU5BQdVAIU9vO9XbDb/gNF29ehWFhYV4+eWXMWfOHFy+fBkbN25Eeno6/vWvf0Eisd7xCRo632bI7cwigqCsrAxLliypd3lQUBBCQkIa/Zz6hmaobrfUDVSb/tuwYQM2b96M/v37qzfEQYMGIScnBxs2bLDqIKhv+6hu50lQTdHR0XBxcVEfZuzfvz/c3d2xePFinDx5Uqt/q9aose+h5mxnFhEETk5OSE1NbfbnyOVyFBUV1Wqvbqtrb8ESaNt/w4YNq9U2dOhQnDx5Eo8fP651SM1aVF948PQvsurtpq4LE6xZUFBQrbbQ0FAAVXsLDIK61bedVc83ZzvjT5UafH19kZubi7y8PI32jIwMeHt7N/mMvCU4d+4cdu3aVau9rKwMNjY2Vv1lV33MNjMzU6M9IyNDYzkBOTk52LVrV60T6NXn31xdXcUoyyz4+PhAJpPV2s6q55uznTEIahg4cCAAICEhQd1WXl6Oo0ePqpdZq/Pnz+ODDz7A1atX1W0qlQoJCQno27dvnZe6WQuFQgFvb2989913Gu2HDh1Cx44d0b59e5EqMz0SiQQfffQRvvzyS432AwcOQCaToV+/fiJVZvrs7e0RGBiIQ4cOaRzGTkhIgLOzM3r27Nnkz7aIQ0P64uXlhfHjx2PFihUoLi6GQqFAXFwc8vLyEBkZKXZ5onrppZfwxRdf4K233sL8+fPh5OSEHTt24Nq1a/jqq6/ELk908+bNw/vvvw8XFxeEhobiyJEjOHjwIKKjo8UuzaS4ublh6tSp+OKLLyCXyxEYGIjExERs3rwZU6dOVV8BQ3WbO3cuZsyYgQULFmD8+PE4d+4ctm3bhoULFzbrclyrHbx+2rRpkMlk2L59u0Z7eXk51qxZg3379qG4uBj+/v5YsmQJAgICxCnUhNy5cwdr167FL7/8gsLCQvTs2RMLFixAYGCg2KWZhJ07dyI2Nhb37t1Dhw4d8MYbb+DFF18UuyyTU1FRge3bt+Prr7/GnTt30KZNG0ycOBGRkZE8sV7DN998g/fffx9Hjx5F27Zt1e3ff/89YmJikJ6ejjZt2mDq1KmYOXNms9ZltUFARERVGL9ERFaOQUBEZOUYBEREVo5BQERk5RgERERWjkFARGTlGARERFaOQUBEZOUYBEREVu7/AU8Z2rQZaMnQAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(df['x'], p1_model.predict(dfp1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part 2A: Fitting Diamond Price Using Carat Data\n",
    "Now let's try building a linear regression model using real data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "file2 = r'D:/Programing/python_projects/machine_learning_algorithm/data_set/diamond_training_data.csv'\n",
    "diamond = pd.read_csv(file2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>carat</th>\n",
       "      <th>cut</th>\n",
       "      <th>color</th>\n",
       "      <th>clarity</th>\n",
       "      <th>depth</th>\n",
       "      <th>table</th>\n",
       "      <th>price</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.00</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>E</td>\n",
       "      <td>I1</td>\n",
       "      <td>61.8</td>\n",
       "      <td>56.0</td>\n",
       "      <td>3520</td>\n",
       "      <td>6.38</td>\n",
       "      <td>6.43</td>\n",
       "      <td>3.96</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.18</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>I</td>\n",
       "      <td>SI2</td>\n",
       "      <td>62.5</td>\n",
       "      <td>55.0</td>\n",
       "      <td>15706</td>\n",
       "      <td>8.31</td>\n",
       "      <td>8.34</td>\n",
       "      <td>5.20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.53</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>H</td>\n",
       "      <td>SI1</td>\n",
       "      <td>62.2</td>\n",
       "      <td>54.0</td>\n",
       "      <td>1205</td>\n",
       "      <td>5.18</td>\n",
       "      <td>5.23</td>\n",
       "      <td>3.24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.30</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>G</td>\n",
       "      <td>VS1</td>\n",
       "      <td>61.5</td>\n",
       "      <td>57.0</td>\n",
       "      <td>605</td>\n",
       "      <td>4.31</td>\n",
       "      <td>4.34</td>\n",
       "      <td>2.66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.76</td>\n",
       "      <td>Premium</td>\n",
       "      <td>E</td>\n",
       "      <td>SI1</td>\n",
       "      <td>58.3</td>\n",
       "      <td>62.0</td>\n",
       "      <td>2937</td>\n",
       "      <td>6.12</td>\n",
       "      <td>5.95</td>\n",
       "      <td>3.52</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   carat      cut color clarity  depth  table  price     x     y     z\n",
       "0   1.00    Ideal     E      I1   61.8   56.0   3520  6.38  6.43  3.96\n",
       "1   2.18    Ideal     I     SI2   62.5   55.0  15706  8.31  8.34  5.20\n",
       "2   0.53    Ideal     H     SI1   62.2   54.0   1205  5.18  5.23  3.24\n",
       "3   0.30    Ideal     G     VS1   61.5   57.0    605  4.31  4.34  2.66\n",
       "4   0.76  Premium     E     SI1   58.3   62.0   2937  6.12  5.95  3.52"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diamond.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a model `carat_model` that tries to predic the price from only the carat data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "carat_model = LinearRegression()\n",
    "carat_model.fit(diamond[['carat']], diamond[['price']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code below computes the mean_absolute_error. It seems that on average, our model is off by around $1,000. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1079.54974806222"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_absolute_error(carat_model.predict(diamond[['carat']]), diamond[['price']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we plot the true relationship between carat and price, as well as the output of your model (in orange)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1ca8f0fc048>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(diamond[['carat']], diamond[['price']])\n",
    "plt.scatter(diamond[['carat']], carat_model.predict(diamond[['carat']]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, use `PolynomialFeatures` to create a 2 dimensional numpy array (or dataframe) called `polynomial_carat_data` that contains carat, carat squared, and carat cubed as features."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "poly = PolynomialFeatures(3)\n",
    "polynomial_carat_data = poly.fit_transform(diamond[['carat']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.      ,  1.      ,  1.      ,  1.      ],\n",
       "       [ 1.      ,  2.18    ,  4.7524  , 10.360232],\n",
       "       [ 1.      ,  0.53    ,  0.2809  ,  0.148877],\n",
       "       ...,\n",
       "       [ 1.      ,  1.16    ,  1.3456  ,  1.560896],\n",
       "       [ 1.      ,  0.55    ,  0.3025  ,  0.166375],\n",
       "       [ 1.      ,  0.57    ,  0.3249  ,  0.185193]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "polynomial_carat_data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we fit a model to the data you just produced."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "poly_carat_model = LinearRegression()\n",
    "poly_carat_model.fit(polynomial_carat_data, diamond[['price']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We see that the error is now on average around \\$893 dollars."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "893.3826766865598"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_absolute_error(poly_carat_model.predict(polynomial_carat_data),\n",
    "                    diamond[['price']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below we can see a scatter plot of your new model. As you can see, even though our error is lower, the model behaves quite strangely for large carat values. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1ca8f15bf08>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(diamond[['carat']], diamond[['price']])\n",
    "plt.scatter(diamond[['carat']], poly_carat_model.predict(polynomial_carat_data))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part 2B: Fitting Diamond Price Using 3rd Degree Polynomial of All Numeric Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To get even more accuracy, create a model `diamond_model` which predicts the price from a 3rd degree polynomial of the `carat`, `depth`, `table`, `x`, `y`, and `z`.\n",
    "\n",
    "Your model should have a total of 84 coefficients.\n",
    "\n",
    "You should also compute the mean absolute error, which should be approximately \\$830."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>carat</th>\n",
       "      <th>depth</th>\n",
       "      <th>table</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.00</td>\n",
       "      <td>61.8</td>\n",
       "      <td>56.0</td>\n",
       "      <td>6.38</td>\n",
       "      <td>6.43</td>\n",
       "      <td>3.96</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.18</td>\n",
       "      <td>62.5</td>\n",
       "      <td>55.0</td>\n",
       "      <td>8.31</td>\n",
       "      <td>8.34</td>\n",
       "      <td>5.20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.53</td>\n",
       "      <td>62.2</td>\n",
       "      <td>54.0</td>\n",
       "      <td>5.18</td>\n",
       "      <td>5.23</td>\n",
       "      <td>3.24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.30</td>\n",
       "      <td>61.5</td>\n",
       "      <td>57.0</td>\n",
       "      <td>4.31</td>\n",
       "      <td>4.34</td>\n",
       "      <td>2.66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.76</td>\n",
       "      <td>58.3</td>\n",
       "      <td>62.0</td>\n",
       "      <td>6.12</td>\n",
       "      <td>5.95</td>\n",
       "      <td>3.52</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   carat  depth  table     x     y     z\n",
       "0   1.00   61.8   56.0  6.38  6.43  3.96\n",
       "1   2.18   62.5   55.0  8.31  8.34  5.20\n",
       "2   0.53   62.2   54.0  5.18  5.23  3.24\n",
       "3   0.30   61.5   57.0  4.31  4.34  2.66\n",
       "4   0.76   58.3   62.0  6.12  5.95  3.52"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "numeric_diamond = diamond[['carat', 'depth', 'table', 'x', 'y', 'z']]\n",
    "numeric_diamond.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "poly = PolynomialFeatures(3)\n",
    "poly_numeric_diamond = poly.fit_transform(numeric_diamond)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diamond_model = LinearRegression()\n",
    "diamond_model.fit(poly_numeric_diamond, diamond[['price']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.20111189e+01, -5.76714372e+07,  4.42610854e+06,\n",
       "        -7.45979884e+05, -6.56258593e+06,  7.23571846e+07,\n",
       "        -8.06074937e+07, -2.82519849e+06,  1.57204712e+06,\n",
       "         1.62312557e+05,  7.79448690e+06,  5.47178226e+06,\n",
       "        -1.75105313e+07, -6.79581816e+04,  2.28231986e+04,\n",
       "         2.68828048e+04, -2.03050951e+06,  2.56295962e+06,\n",
       "         2.08653255e+03,  3.69281004e+05, -1.61617957e+05,\n",
       "        -4.08560137e+05, -1.80835710e+04, -4.94946460e+06,\n",
       "         4.51435216e+06, -8.58148788e+06,  3.22032800e+07,\n",
       "        -2.52037459e+07,  1.05654336e+04,  3.89574155e+04,\n",
       "         8.10979849e+03,  1.72767508e+05,  1.15580636e+05,\n",
       "        -4.90256191e+05, -1.07655739e+04, -2.11694613e+03,\n",
       "        -1.10400193e+05, -7.62454145e+04,  2.47401906e+05,\n",
       "        -4.26035677e+01, -1.00564452e+04, -5.86117051e+03,\n",
       "         1.47437247e+04, -6.68394300e+05,  2.92211518e+05,\n",
       "         1.46398231e+06, -5.19288461e+05,  1.04763308e+06,\n",
       "        -1.70395391e+06,  3.52795955e+02, -1.65069285e+02,\n",
       "         1.28352088e+03,  1.38801181e+04, -2.00757760e+04,\n",
       "        -3.78546238e+01, -5.53524777e+03,  2.78739827e+03,\n",
       "         5.33900539e+03,  8.93903593e+02,  9.99970336e+04,\n",
       "        -1.18216421e+05,  1.00221754e+05, -4.31584657e+05,\n",
       "         3.80695062e+05,  1.42890699e+00, -3.71397752e+02,\n",
       "        -1.05665008e+02,  7.79494760e+02, -2.14793622e+04,\n",
       "        -8.19964838e+03,  8.90191708e+04,  2.03595484e+04,\n",
       "        -5.17354538e+04, -3.24194594e+04,  1.06577676e+05,\n",
       "         1.16766560e+05, -2.66520640e+05,  3.40615471e+05,\n",
       "        -1.79423624e+06,  1.50554523e+06,  2.73124446e+05,\n",
       "        -1.42095432e+06,  3.30267646e+06, -2.21474593e+06]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diamond_model.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "84"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(diamond_model.coef_[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "830.2478295669754"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_absolute_error(diamond_model.predict(poly_numeric_diamond),\n",
    "                    diamond[['price']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part 2C: Plotting Training MSE vs. Polynomial Degree"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's now explore how training error varies as a function of the diamond price. For this part, we've provided the code for you, though you might find it interesting to try to write it yourself."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_training_mae(degree):\n",
    "    poly = PolynomialFeatures(degree=degree)\n",
    "    poly_numeric_diamond = poly.fit_transform(numeric_diamond)\n",
    "    diamond_model = LinearRegression()\n",
    "    diamond_model.fit(poly_numeric_diamond, diamond[['price']])\n",
    "    return mean_absolute_error(diamond_model.predict(poly_numeric_diamond),\n",
    "                               diamond[['price']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "maes = [get_training_mae(i) for i in range(0, 6)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3134.287018666666,\n",
       " 977.2853873048613,\n",
       " 861.6348478382624,\n",
       " 830.2478295669754,\n",
       " 770.8458326009114,\n",
       " 729.1646799418131]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "maes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x1ca8f1bd348>]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(maes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part 2D: Plotting Validation MAE vs. Polynomial Degree"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, you will create a plot of the mean absolute error on the validation data set stored in the file \"diamond_validation_data.csv\". The first two cells are provided for you."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>carat</th>\n",
       "      <th>cut</th>\n",
       "      <th>color</th>\n",
       "      <th>clarity</th>\n",
       "      <th>depth</th>\n",
       "      <th>table</th>\n",
       "      <th>price</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.51</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>E</td>\n",
       "      <td>SI1</td>\n",
       "      <td>61.5</td>\n",
       "      <td>57.0</td>\n",
       "      <td>1682</td>\n",
       "      <td>5.11</td>\n",
       "      <td>5.16</td>\n",
       "      <td>3.16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.70</td>\n",
       "      <td>Very Good</td>\n",
       "      <td>H</td>\n",
       "      <td>SI1</td>\n",
       "      <td>61.5</td>\n",
       "      <td>57.0</td>\n",
       "      <td>2107</td>\n",
       "      <td>5.64</td>\n",
       "      <td>5.68</td>\n",
       "      <td>3.48</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.09</td>\n",
       "      <td>Very Good</td>\n",
       "      <td>G</td>\n",
       "      <td>VS1</td>\n",
       "      <td>62.5</td>\n",
       "      <td>59.0</td>\n",
       "      <td>6827</td>\n",
       "      <td>6.54</td>\n",
       "      <td>6.57</td>\n",
       "      <td>4.10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1.80</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>F</td>\n",
       "      <td>SI1</td>\n",
       "      <td>61.8</td>\n",
       "      <td>57.0</td>\n",
       "      <td>16513</td>\n",
       "      <td>7.83</td>\n",
       "      <td>7.79</td>\n",
       "      <td>4.83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.71</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>D</td>\n",
       "      <td>VS1</td>\n",
       "      <td>60.9</td>\n",
       "      <td>57.0</td>\n",
       "      <td>3518</td>\n",
       "      <td>5.74</td>\n",
       "      <td>5.76</td>\n",
       "      <td>3.50</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   carat        cut color clarity  depth  table  price     x     y     z\n",
       "0   0.51      Ideal     E     SI1   61.5   57.0   1682  5.11  5.16  3.16\n",
       "1   0.70  Very Good     H     SI1   61.5   57.0   2107  5.64  5.68  3.48\n",
       "2   1.09  Very Good     G     VS1   62.5   59.0   6827  6.54  6.57  4.10\n",
       "3   1.80      Ideal     F     SI1   61.8   57.0  16513  7.83  7.79  4.83\n",
       "4   0.71      Ideal     D     VS1   60.9   57.0   3518  5.74  5.76  3.50"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "file3 = r'D:/Programing/python_projects/machine_learning_algorithm/data_set/diamond_validation_data.csv'\n",
    "diamond_validation = pd.read_csv(file3)\n",
    "diamond_validation.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "numeric_diamond_validation = diamond_validation[[\n",
    "    \"carat\", \"depth\", \"table\", \"x\", \"y\", \"z\"\n",
    "]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To complete this exercise, fill in the function below so that it returns the training error and validation error for a polynomial of the given degree.\n",
    "\n",
    "The function should return two values: The first is the trainig error and the second is the validation error.\n",
    "\n",
    "Hint: You can copy and paste code from the get_training_mae function above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_training_and_validation_mae(degree):\n",
    "    poly = PolynomialFeatures(degree)\n",
    "    poly_diamond_training = poly.fit_transform(numeric_diamond)\n",
    "    poly_diamond_validation = poly.fit_transform(numeric_diamond_validation)\n",
    "    diamond_model = LinearRegression()\n",
    "    diamond_model.fit(poly_diamond_training, diamond[['price']])\n",
    "    training_error = mean_absolute_error(\n",
    "        diamond_model.predict(poly_diamond_training), diamond[['price']])\n",
    "    validation_error = mean_absolute_error(\n",
    "        diamond_model.predict(poly_diamond_validation),\n",
    "        diamond_validation[['price']])\n",
    "    return training_error, validation_error"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If your code is working correctly, the following cell should output 977.285 and 957.432."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(977.2853873048613, 957.432016384659)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_training_and_validation_mae(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code below will plot the training and validation error. Note that as polynomial degree goes up, we start seeing overfitting (where validation error starts going up again)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "maes = np.array([get_training_and_validation_mae(i) for i in range(0, 6)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 3134.28701867,  3095.9604    ],\n",
       "       [  977.2853873 ,   957.43201638],\n",
       "       [  861.63484784,   859.40218723],\n",
       "       [  830.24782957,  1113.93262317],\n",
       "       [  770.8458326 ,  3072.69473773],\n",
       "       [  729.16467994, 16119.84594785]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "maes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x1ca90822d08>"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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06d7Ohy3Kioq4o477uC2225zau/YsSNQvdxPY2AwGPjHP/7B5MmTndpNJhNlZWUeiqr+zJw5k+TkZPr37+/pUNzu0KFDtG/fnoCAALftQxJKDfnqfVhiYmLYuHEjDz/8MAaDwdPhuFVQUBAzZ86kT58+Tu0bN24EIDY21hNhuZWqqnTu3JnIyEh0Xef8+fMsXbqU1NRU7r33Xk+H51YrV67khx9+4M9//rOnQ6kXR44cwWw2M3HiROLj40lMTGTWrFkunR+UOZQacuV9WBqS5s2bezoEj9q/fz9Lly5l+PDhxMTEeDoct1q/fj2PPvooAEOGDOGOO+7wcETuc/r0aebNm8e8efMICwvzdDj14vDhwxQWFnL33XczdepUvv/+e15//XUyMzNZvnx5tVuC3AhJKDWku/A+LKJhSEtLY+rUqbRt25a5c+d6Ohy369q1K++//z5HjhzhtddeY/LkySxfvtzTYbmcrus888wzDB48mJEjR3o6nHqzaNEimjVrRufOnQFITEwkPDycGTNmkJqaSnJycp33IQmlhuQ+LL5l3bp1PPXUU0RFRfH2228TGhrq6ZDcrl27drRr147ExESCgoJ48skn+fbbb116Wak3WLFiBUeOHOHTTz91XLVY+cHQarViMBhc8mnd2/Tt27da25AhQwD70YsrEop8rK4huQ+L73j33XeZNm0aN998MytWrKBFixaeDslt8vLyWL16NT/++KNTe9euXQGqtTcGX3zxBRcvXiQlJYVu3brRrVs3Vq9eTXZ2Nt26deO///2vp0N0udzcXFauXFnt4qHS0lIAl31gkoRSQ3IfFt+wcuVKXnzxRUaPHs3bb7/d6I88NU3jqaee4oMPPnBq37FjBwBxcXGeCMut/vKXv/Dhhx86/QwdOpSWLVs6Hjc2iqIwa9Ys3n//faf2devWYTAYql2IcqPklFctyH1YGrfc3Fyef/552rRpw3333cfBgwedlrdv377RTeCGhYUxduxYli5dir+/Pz169CAtLY233nqLu+++23HJdGNypTGFhIRgNpvp0aOHByJyv7CwMO677z7+8Y9/EBQUREJCAmlpaSxZsoT77rvPcbVqXUlCqYVf/vKXlJeXs2zZMlauXEm7du2YP3++T3yb2Bd89dVXlJSUcPr0ae67775qyxcsWMDPf/5zD0TmXk8//TStWrXiww8/5PXXX6dly5Y88sgjTJo0ydOhCRd68skniYyMZNWqVSxdupTIyEgeffRRl/6d5X4oQgghXELmUIQQQriEJBQhhBAuIQlFCCGES0hCEUII4RKSUIQQQriEJBQhhBAuIQlFCCGES0hCEUII4RKSUIQQQrjE/wd3ckD+BmMs1AAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(maes[:, 0])\n",
    "plt.plot(maes[:, 1])\n",
    "plt.legend(['training', 'validation'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part 3: Perfect Accuracy?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This one is a tricky bonus question."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "#set aside only the numeric columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>carat</th>\n",
       "      <th>depth</th>\n",
       "      <th>table</th>\n",
       "      <th>price</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.00</td>\n",
       "      <td>61.8</td>\n",
       "      <td>56.0</td>\n",
       "      <td>3520</td>\n",
       "      <td>6.38</td>\n",
       "      <td>6.43</td>\n",
       "      <td>3.96</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.18</td>\n",
       "      <td>62.5</td>\n",
       "      <td>55.0</td>\n",
       "      <td>15706</td>\n",
       "      <td>8.31</td>\n",
       "      <td>8.34</td>\n",
       "      <td>5.20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.53</td>\n",
       "      <td>62.2</td>\n",
       "      <td>54.0</td>\n",
       "      <td>1205</td>\n",
       "      <td>5.18</td>\n",
       "      <td>5.23</td>\n",
       "      <td>3.24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.30</td>\n",
       "      <td>61.5</td>\n",
       "      <td>57.0</td>\n",
       "      <td>605</td>\n",
       "      <td>4.31</td>\n",
       "      <td>4.34</td>\n",
       "      <td>2.66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.76</td>\n",
       "      <td>58.3</td>\n",
       "      <td>62.0</td>\n",
       "      <td>2937</td>\n",
       "      <td>6.12</td>\n",
       "      <td>5.95</td>\n",
       "      <td>3.52</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   carat  depth  table  price     x     y     z\n",
       "0   1.00   61.8   56.0   3520  6.38  6.43  3.96\n",
       "1   2.18   62.5   55.0  15706  8.31  8.34  5.20\n",
       "2   0.53   62.2   54.0   1205  5.18  5.23  3.24\n",
       "3   0.30   61.5   57.0    605  4.31  4.34  2.66\n",
       "4   0.76   58.3   62.0   2937  6.12  5.95  3.52"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diamond_data_numeric_only = diamond.select_dtypes(['number'])\n",
    "diamond_data_numeric_only.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p3_model = LinearRegression()\n",
    "p3_model.fit(diamond_data_numeric_only, diamond_data_numeric_only[\"price\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0658393887350493e-24"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_squared_error(p3_model.predict(diamond_data_numeric_only),\n",
    "                   diamond_data_numeric_only[\"price\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we see the mean squared error is extremely low -- it is effectively zero. How did this happen? Is this model useful?\n",
    "\n",
    "Hint: Look at the coefficients of the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 2.49547047e-12,  2.49489546e-13, -1.50202482e-14,  1.00000000e+00,\n",
       "        7.49426858e-14,  7.34939892e-14, -2.04450610e-13])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p3_model.coef_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution: The issue is that we've included mpg in the set of features that we use to make predictions. Given mpg, it's pretty easy to predict mpg (you just set that theta to 1 and all others to 0)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
